package com.gopay.scheduler.shedulerx.remote;

import com.gopay.common.constants.scheduler.SchedulerConstants;
import com.gopay.common.util.JsonUtils;
import com.gopay.remote.cron.SchedulerXRemoteService;
import com.gopay.scheduler.shedulerx.JobConfig;
import com.gopay.scheduler.shedulerx.SchedulerOperateFactory;
import com.gopay.scheduler.shedulerx.rdb.JobConfigRepository;
import com.gopay.scheduler.shedulerx.util.RedisOperator;
import org.apache.commons.lang3.StringUtils;
import org.quartz.JobKey;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * @author 19371
 */
@Service
public class CronRemoteService implements SchedulerXRemoteService {


    @Override
    public String trigger(String jobName) {
        String res = SchedulerConstants.FAIL;
        try {
            infoLog(String.format("the jobName is %s ; the endpoint is /trigger",jobName));
            res =  SchedulerOperateFactory.getFactory().getSchedulerControl().trigger(new JobKey(jobName));
        } catch (SchedulerException e) {
            exceptionLog(e,String.format("the jobName is %s ; the endpoint is /trigger",jobName));
        }
        return res;
    }

    @Override
    public String pause(String jobName) {
        String res = SchedulerConstants.FAIL;
        try {
            infoLog(String.format("the jobName is %s ; the endpoint is /pause",jobName));
            res =  SchedulerOperateFactory.getFactory().getSchedulerControl().pause(new JobKey(jobName));
            SchedulerOperateFactory factory = SchedulerOperateFactory.getFactory();
            RedisOperator.setJobOperateCache(factory.getAppName()+SchedulerConstants.SCHEDULER_HORIZONTAL_LINE+factory.getRunEnv()+SchedulerConstants.SCHEDULER_HORIZONTAL_LINE+SchedulerConstants.OPERATE,jobName,SchedulerConstants.OPERATE_PAUSE);
        } catch (Exception e) {
            exceptionLog(e,String.format("the jobName is %s ; the endpoint is /pause",jobName));
        }
        return res;
    }

    @Override
    public String resume(String jobName) {
        String res = SchedulerConstants.FAIL;
        try {
            infoLog(String.format("the jobName is %s ; the endpoint is /resume",jobName));
            res = SchedulerOperateFactory.getFactory().getSchedulerControl().resume(new JobKey(jobName));
            SchedulerOperateFactory factory = SchedulerOperateFactory.getFactory();
            RedisOperator.delJobOperateCache(factory.getAppName()+SchedulerConstants.SCHEDULER_HORIZONTAL_LINE+factory.getRunEnv()+SchedulerConstants.SCHEDULER_HORIZONTAL_LINE+SchedulerConstants.OPERATE,jobName);
        } catch (Exception e) {
            exceptionLog(e,String.format("the jobName is %s ; the endpoint is /resume",jobName));
        }
        return res;
    }


    @Override
    public boolean luckyParam(String jobName,String luckyJson){
        SchedulerOperateFactory operateFactory = SchedulerOperateFactory.getFactory();
        try {
            infoLog(String.format("the jobName is %s ; the endpoint is /luckyParam",jobName));
            return operateFactory.setLuckyParam(jobName,luckyJson);
        } catch (Exception e) {
            exceptionLog(e,String.format("the jobName is %s ,the json is %s ; the endpoint is /luckyParam",jobName,luckyJson));
            return false;
        }
    }

    @Override
    public boolean clearLuckyParam(String jobName){
        SchedulerOperateFactory operateFactory = SchedulerOperateFactory.getFactory();
        try {
            infoLog(String.format("the jobName is %s ; the endpoint is /clearLuckyParam",jobName));
            return operateFactory.clearLuckyParam(jobName);
        } catch (Exception e) {
            exceptionLog(e,String.format("the jobName is %s ; the endpoint is /clearLuckyParam",jobName));
            return false;
        }
    }

    @Override
    public String lookupLuckParam(String jobName) {
        SchedulerOperateFactory operateFactory = SchedulerOperateFactory.getFactory();
        try {
            infoLog(String.format("the jobName is %s ; the endpoint is /lookupLuckParam",jobName));
            return operateFactory.getLuckyParam(jobName);
        } catch (Exception e) {
            exceptionLog(e,String.format("the jobName is %s ; the endpoint is /lookupLuckParam",jobName));
            return SchedulerConstants.FAIL;
        }
    }

    @Override
    public String triggerState(String jobName) {
        String res = SchedulerConstants.FAIL;
        try {
            infoLog(String.format("the jobName is %s ; the endpoint is /triggerState",jobName));
            res = SchedulerOperateFactory.getFactory().getSchedulerControl().fishTriggerState(jobName);
        } catch (Exception e) {
            exceptionLog(e,"/triggerState");
        }
        return res;
    }

    @Override
    public String saveConfig(Map<String, Object> jobConfigMap) {
        try {
            infoLog(String.format("保存配置信息 the endpoint is /saveConfig; the param=%s",JsonUtils.toJson(jobConfigMap)));
            JobConfig jobConfig = new JobConfig();
            if(StringUtils.isBlank(jobConfigMap.get("jobId")+"")){
                return SchedulerConstants.FAIL;
            }
            jobConfig.setJobId(String.valueOf(jobConfigMap.get("jobId")));
            List<JobConfig> jobConfigs = JobConfigRepository.getSingle().selectJobConfigById(jobConfig.getJobId());
            JobConfig jobConfigBefore = jobConfigs.get(0);
            if(jobConfigBefore == null){
                LOGGER.info(String.format("保存配置信息 the endpoint is /saveConfig; the param=%s------>查询不到匹配信息",JsonUtils.toJson(jobConfigMap)));
                return SchedulerConstants.FAIL;
            }
            String decription = jobConfigMap.get("decription")+"";
            String alarm = jobConfigMap.get("alarm")+"";
            String eventControl = jobConfigMap.get("eventControl")+"";
            if(StringUtils.isNotBlank(decription) && !decription.equals(jobConfigBefore.getDecription())){
                jobConfig.setDecription(decription);
            }
            if(StringUtils.isNotBlank(alarm) && !alarm.equals(jobConfigBefore.getAlarm())){
                jobConfig.setAlarm(alarm);

            }
            if(StringUtils.isNotBlank(eventControl) && !eventControl.equals(jobConfigBefore.getEventControl())){
                jobConfig.setEventControl(eventControl);
                }
                if(JobConfigRepository.getSingle().updateJobConfig(jobConfig)) {
                SchedulerOperateFactory operateFactory = SchedulerOperateFactory.getFactory();
                if (StringUtils.isNotBlank(alarm) && !alarm.equals(jobConfigBefore.getAlarm())) {
                        operateFactory.getAlarmLevelMapping().put(jobConfigBefore.getJobClass(), alarm);
                        LOGGER.info(String.format("更新Job配置成功------>jobName=%s:alarm from %s to %s",jobConfigBefore.getJobName(),jobConfigBefore.getAlarm(),operateFactory.getAlarmLevelMapping().get(jobConfigBefore.getJobClass())));
                    }
                    if (StringUtils.isNotBlank(eventControl) && !eventControl.equals(jobConfigBefore.getEventControl())) {
                         operateFactory.getEventSet().put(jobConfigBefore.getJobClass(), eventControl);
                        LOGGER.info(String.format("更新Job配置成功------>jobName=%s:eventControl from %s to %s",jobConfigBefore.getJobName(),jobConfigBefore.getEventControl(),operateFactory.getEventSet().get(jobConfigBefore.getJobClass())));
                    }
                    if (StringUtils.isNotBlank(decription) && !decription.equals(jobConfigBefore.getDecription())) {
                        operateFactory.getJobDescription().put(jobConfigBefore.getJobName(), decription);
                        LOGGER.info(String.format("更新Job配置成功------>jobName=%s:description from %s to %s",jobConfigBefore.getJobName(),jobConfigBefore.getDecription(),operateFactory.getJobDescription().get(jobConfigBefore.getJobName())));
                    }
                    return SchedulerConstants.OK;
                }

        } catch (Exception e) {
            exceptionLog(e,"/saveConfig");
        }
        return SchedulerConstants.FAIL;
    }

    private final static Logger LOGGER = LoggerFactory.getLogger(CronRemoteService.class);

    private void exceptionLog(Exception e,String description){
        LOGGER.error(String.format("the scheduler occur error ,the  description is {%s}",description),e);
    }
    private void infoLog(String description){
        LOGGER.info(String.format("the scheduler log : %s",description));
    }
}
